package com.ycwl.freetv;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.WindowInsetsControllerCompat;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.Player;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.audio.AudioMixingUtil;
import androidx.media3.ui.PlayerView;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsoluteLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.ycwl.freetv.program.Program;
import com.ycwl.freetv.utils.FileUtils;
import com.ycwl.library.AssetsListManager;
import com.ycwl.library.ParseUIFromJson;
import com.ycwl.library.Utils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class AdActivity extends BaseActivity {
    final class AdCmd {
        private static final int resetSource = 1;
        private static final int nextProgram = 2;
        private static final int initAssets = 3;
        private static final int updatePlayList = 4;
    }
    protected String rootPath = "";
    protected String abConfigFile = "";


    protected boolean isPlaying = false;


    protected Program program = null;

    protected Ad adData;

    protected Runnable runnable = new Runnable() {
        @Override
        public void run() {
            int count = AssetsListManager.getInstance().getProgramCount();
            while (count > 0) {
                if (!isPlaying) {
                    return;
                }
                ParseUIFromJson.MProgram mProgram = AssetsListManager.getInstance().getNextProgram();

                if (mProgram.effect_time * 1000L > System.currentTimeMillis()
                        || mProgram.expiration_time * 1000L < System.currentTimeMillis()
                        || mProgram.total_time.intValue() <= 0) {
                    Message message2 = new Message();
                    message2.what = 1000;
                    message2.obj =  "节目：[" + mProgram.name + "] 已经过期，不在播放";
                    Log.w(TAG,(String) message2.obj + count);
                    playerHandler.sendMessage(message2);
                    count--;
                    continue;
                }
                Message message = new Message();
                message.what = AdCmd.nextProgram;
                message.obj = mProgram;
                playerHandler.sendMessage(message);
                playerHandler.postDelayed(this,mProgram.total_time.intValue()* 1000L);
                break;
            }
        }
    };

    class Ad {
        class Vdio {
            class Images {
                public String uri = "";
                public String description = "";
            }

            public String name = "";
            public String uri = "";
            public String time = "";
            public String index = "";
            public List<Images> images;


        }

        public String description = "";
        public String starttime = "";
        public String endtime = "";
        public List<Vdio> content;


    }
    protected HashMap<String, String> assetsMap = new HashMap<>();

    Handler playerHandler = new Handler(Looper.myLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case AdCmd.resetSource:
                    Log.d(TAG, "开始刷新视屏");
                    break;
                case AdCmd.nextProgram:
                    Log.d(TAG, "开始下一个节目");

                    Program tempProgram = new Program.Builder(getApplicationContext(),(ParseUIFromJson.MProgram) msg.obj).build();
                    setContentView(tempProgram.getView());
                    tempProgram.play();

                    if (program != null) {
                        program.stop();
                    }
                    program = tempProgram;
                    System.gc();
                    break;
                case AdCmd.initAssets:
                    stopPlay();
                    initAssets();
                    break;
                case AdCmd.updatePlayList:
                    AssetsListManager.getInstance().setProgramIndex(0);
                    AssetsListManager.getInstance().setmPlayList((ParseUIFromJson.MPlayList) msg.obj);
                    startPlay();
                    break;
                default:
                    Toast toast = Toast.makeText(getApplicationContext(), (String)msg.obj, Toast.LENGTH_LONG);
                    toast.show();
            }

        }
    };

    protected void refreshAd() {
        Gson gson = new Gson();
        File file = new File(abConfigFile);
        String jsonStr = FileUtils.readTextFromFile(file.getAbsolutePath());
        Ad ad = gson.fromJson(jsonStr, Ad.class);
        Log.d(TAG, ad.description);
        adData = ad;
        Message message = new Message();
        message.what = 1;
        playerHandler.sendMessage(message);
    }


    public void initAssets() {
        Log.i(TAG, "taoliuchang UI");
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "taoliuchang handle");
                Message message = new Message();
                message.what = 1000;
                message.obj = "开始初始化资源,请耐心等待";
                playerHandler.sendMessage(message);
                AssetsListManager.getInstance().importAssetsByDir(AssetsListManager.getInstance().getAssetsCachePath(), 1);
                ParseUIFromJson.MPlayList mPlayList = ParseUIFromJson.parseUIFromJson(FileUtils.readTextFromFile(AssetsListManager.getInstance().getConfigFilePath()+File.separator+"playlist.json"));
                if (mPlayList == null) {
                    Message message1 = new Message();
                    message1.what = 1000;
                    message1.obj = "没有可以播放节目，请更新播放列表";
                    playerHandler.sendMessage(message1);
                    return;
                }
                Message message2 = new Message();
                message2.what = AdCmd.updatePlayList;
                message2.obj = mPlayList;
                playerHandler.sendMessage(message2);

                Message message1 = new Message();
                message1.what = 1000;
                message1.obj = "资源加载完毕";
                playerHandler.sendMessage(message1);
            }
        }).start();
    }
    public void startPlay() {
        isPlaying = true;
        playerHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                int count = AssetsListManager.getInstance().getProgramCount();
                while (count > 0) {
                    if (!isPlaying) {
                        return;
                    }
                    ParseUIFromJson.MProgram mProgram = AssetsListManager.getInstance().getCurrentProgram();

                    if (mProgram.effect_time * 1000L > System.currentTimeMillis()
                            || mProgram.expiration_time * 1000L < System.currentTimeMillis()
                            || mProgram.total_time.intValue() <= 0) {
                        Message message2 = new Message();
                        message2.what = 1000;
                        message2.obj =  "节目：[" + mProgram.name + "] 已经过期，不在播放";
                        Log.w(TAG,(String) message2.obj + count);
                        playerHandler.sendMessage(message2);
                        count--;
                        continue;
                    }
                    Message message = new Message();
                    message.what = AdCmd.nextProgram;
                    message.obj = mProgram;
                    playerHandler.sendMessage(message);
                    playerHandler.postDelayed(runnable,mProgram.total_time.intValue()* 1000L);
                    break;
                }
            }
        }, 100L);
    }

    public void stopPlay() {
        isPlaying = false;
        playerHandler.removeCallbacks(runnable);
        if (program != null) {
            program.stop();
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        boolean isRequestOk = true;
        for (int i=0;i< permissions.length;i++) {
            if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG,"permission "+permissions[i]+"; result: 允许");
            } else if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                Log.d(TAG,"permission "+permissions[i]+"; result: 拒绝");
                isRequestOk = false;
            } else {
                Log.d(TAG,"permission "+permissions[i]+"; result:"+grantResults[i]);
            }
        }
        // 扩展内存申请
        if (requestCode == 1 && isRequestOk) {
            playerHandler.sendEmptyMessage(AdCmd.initAssets);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG,"onCreate");
        AssetsListManager.getInstance().init(this);
        TextView textView = new TextView(this);
        textView.setText("正在初始化资源，请耐心等待...");
        RelativeLayout.LayoutParams layoutParams = new  RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
        layoutParams.topMargin = ViewGroup.LayoutParams.WRAP_CONTENT;
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
        textView.setLayoutParams(layoutParams);
        textView.setTextSize(60);
        RelativeLayout relativeLayout = new RelativeLayout(this);
        relativeLayout.addView(textView);
        this.setContentView(relativeLayout);
        WindowInsetsControllerCompat windowInsetsController =
                WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView());
        // Configure the behavior of the hidden system bars.
        windowInsetsController.setSystemBarsBehavior(
                WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        );
        windowInsetsController.hide(WindowInsetsCompat.Type.systemBars());
    }


    @Override
    protected void onUsbReady(String path) {
        Log.i(TAG,"onUsbReady: " + path);
        new Thread(new Runnable() {
            @Override
            public void run() {
                broadcastHandler.sendEmptyMessage(Cmd.copySource);
                List<String> stringList = FileUtils.scanFileInByDir(path,"freetv\\.zip$",1);
                if (stringList.size() == 0) {
                    Message message = new Message();
                    message.what = 1000;
                    message.obj = "u盘根目录中没有找到\"freetv.zip\"更新资源包";
                    playerHandler.sendMessage(message);
                    return;
                }
                String sourceFile = null;
                String playListFilePath = null;
                for (String filePath : stringList) {
                    playListFilePath = Utils.checkSourceFile(filePath,".*playlist_[a-fA-F0-9]{40}\\.json$");
                    if (playListFilePath != null) {
                        sourceFile = filePath;
                        break;
                    }
                }
                if (sourceFile == null) {
                    Message message = new Message();
                    message.what = 1000;
                    message.obj = "u盘根目录中找到\"freetv.zip\"更新资源包不包含有效播放列表文件，放弃更新资源";
                    playerHandler.sendMessage(message);
                    return;
                }

                HashMap<String,AssetsListManager.Assets> hashMap = FileUtils.getAllAssetsInZip(sourceFile);
                String playJsonString = Utils.ReadFileFromCompressed(sourceFile, playListFilePath);

                try {
                    Gson gson = new Gson();
                    ParseUIFromJson.MPlayList mPlayList = gson.fromJson(playJsonString, ParseUIFromJson.MPlayList.class);
                    for (ParseUIFromJson.MProgram program: mPlayList.programs) {
                        filterRealData(program.view, hashMap);
                    }
                    Log.i(TAG,"ok");
                    for(AssetsListManager.Assets assets : hashMap.values()) {
                        if (assets.quote > 0) {
                            String destFileName = AssetsListManager.getInstance().getAssetsCachePath() + File.separator + assets.sha1 + "." + FileUtils.getFileExtension(assets.name);
                            Utils.copyFromZip(assets.path,assets.name,destFileName);
                        }
                    }

                    // 将播放列表保存到当前指定文件中
                    String playConfigFileName = AssetsListManager.getInstance().getConfigFilePath()+File.separator+"playlist.json";
                    OutputStream os  = new BufferedOutputStream(new FileOutputStream(playConfigFileName,false));

                    assert playJsonString != null;
                    os.write(playJsonString.getBytes());
                    os.flush();
                    os.close();
                    // 重新初始化资源
                    Message message = new Message();
                    message.what = 1000;
                    message.obj = "U盘数据同步完成，正在初始化文件资源和播放列表";
                    broadcastHandler.sendMessage(message);
                    playerHandler.sendEmptyMessage(AdCmd.initAssets);
                } catch (JsonSyntaxException | IOException ignored) {
                    Message message = new Message();
                    message.what = 1000;
                    message.obj = "文件同步失败";
                    broadcastHandler.sendMessage(message);
                }
                broadcastHandler.sendEmptyMessage(Cmd.copyOver);
            }
        }).start();

    }

    private void filterRealData(ParseUIFromJson.BaseNode baseNode, HashMap<String,AssetsListManager.Assets> hashMap) {
        if (baseNode.type == ParseUIFromJson.NODE_TYPE.VIDEO || baseNode.type == ParseUIFromJson.NODE_TYPE.IMAGE) {
            AssetsListManager.Assets assets = null;
            assets = AssetsListManager.getInstance().getAssetsByHash(baseNode.sha1);
            if (assets != null) {
                assets.quote = assets.quote + 1;
                return;
            }
            if (hashMap.containsKey(baseNode.sha1)) {
                assets = hashMap.get(baseNode.sha1);
                if (assets != null) {
                    assets.quote = assets.quote + 1;
                }
            }
            if (assets == null) {
                Message message = new Message();
                message.what = 1000;
                message.obj =  "文件:[ "+ baseNode.content + " ] 不存在";
                broadcastHandler.sendMessage(message);
                return;
            }
            baseNode.url = assets.path;
            assets.quote++;
        } else {
            for (ParseUIFromJson.BaseNode item :baseNode.children) {
                filterRealData(item, hashMap);
            }
        }
    }


    protected String FindConfigFile(File dir) {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    String res = FindConfigFile(file);  // 递归遍历子目录
                    if (!res.isEmpty()) {
                        return res;
                    }
                } else {
                    System.out.println(file.getAbsolutePath());  // 输出文件路径
                    Log.d(TAG, file.getAbsolutePath() + "; filename:" + file.getName());
                    if (file.getName().contains("adconfig_")) {
                        return file.getAbsolutePath();
                    }
                }
            }
        }
        return "";
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG,"onStart");
        List<String> permissionList = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }

        String[] permissionArray =  permissionList.toArray(new String[0]);
        if (permissionArray.length > 0) {
            Log.d(TAG,"permission request");
            for(String str: permissionList) {
                Log.d(TAG,"permission request :" + str);
            }
            ActivityCompat.requestPermissions(this, permissionArray,1);
        } else {
            if (AssetsListManager.getInstance().getProgramCount() > 0) {
                startPlay();
                return;
            }
            initAssets();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG,"onStop");
        stopPlay();
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG,"onPause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG,"onResume");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG,"onDestroy");
    }

}